package com.weimengchao.task.handler;

import com.csvreader.CsvReader;
import com.weimengchao.task.exception.ReportIsEmptyException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.lang3.ArrayUtils;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: 报表转换：读取报表，解密并生成新的报表
 * @author: 魏孟超
 * @createDate: 2021-10-17 16:16
 */
public abstract class AbstractReportConvert {

    private Map<String, Integer> titleMap = new HashMap<>();
    private List<Character> illegalCharacters;

    public byte[] readForCSV(File file) throws Exception {
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            return readForCSV(fileInputStream);
        }
    }

    public byte[] readForCSV(InputStream inputStream) throws Exception {
        byte[] bytes = null;
        CsvReader csvReader = null;
        OutputStreamWriter outputStreamWriter = null;
        CSVPrinter csvPrinter = null;
        ByteArrayOutputStream outputStream = null;
        try {
            outputStream = new ByteArrayOutputStream();
            csvReader = new CsvReader(inputStream, ',', Charset.forName(charsetName()));
            outputStreamWriter = new OutputStreamWriter(outputStream, charsetName());
            csvPrinter = CSVFormat.DEFAULT.print(outputStreamWriter);
            if (csvReader.readRecord()) {
                String[] values = csvReader.getValues();
                List<String> titleData = arrayToList(values);
                fillTitleMap(titleData);
                List<String> newTitleData = titleData(titleData);
                csvPrinter.printRecord(newTitleData);
            } else {
                throw new ReportIsEmptyException("报表为空");
            }
            while (csvReader.readRecord()) {
                List<String> newRowData = rowData(arrayToList(csvReader.getValues()));
                csvPrinter.printRecord(newRowData);
            }
            csvPrinter.flush();
            bytes = outputStream.toByteArray();
        } catch (Exception e) {
            throw e;
        } finally {
            if (null != csvPrinter) {
                csvPrinter.close();
            }
            if (outputStreamWriter != null) {
                outputStreamWriter.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (null != csvReader) {
                csvReader.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return bytes;
    }

    /**
     * list转Map
     *
     * @param newTitleData
     */
    private void fillTitleMap(List<String> newTitleData) {
        int index = 0;
        for (String title : newTitleData) {
            titleMap.put(title, index);
            index++;
        }
    }


    /**
     * @description: 数组转集合
     * @createAuthor: 魏孟超
     * @createDate: 2021/10/17 16:30
     * @params:
     * @return:
     */
    private List<String> arrayToList(String[] arr) {
        List<String> list = new ArrayList<>();
        if (ArrayUtils.isEmpty(arr)) {
            return list;
        }
        for (int i = 0; i < arr.length; i++) {
            String s = cleanString(arr[i]);
            list.add(s);
        }
        return list;
    }

    /**
     * @description: 去除非法字符
     * @createAuthor: 魏孟超
     * @createDate: 2021/10/17 17:41
     * @params:
     * @return:
     */
    private String cleanString(String str) {
        StringBuffer buffer = new StringBuffer();
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            illegalCharacters = getIllegalCharacters();
            if (illegalCharacters.contains(chars[i])) {
                continue;
            }
            buffer.append(chars[i]);
        }
        return buffer.toString();
    }

    /**
     * @description: 获取非法字符
     * @createAuthor: 魏孟超
     * @createDate: 2021/10/17 18:08
     * @params:
     * @return:
     */
    private List<Character> getIllegalCharacters() {
        if (CollectionUtils.isEmpty(illegalCharacters)) {
            illegalCharacters = new ArrayList<>();
        }
        illegalCharacters.add((char) 65279);
        illegalCharacters.add((char) 9);
        return illegalCharacters;
    }

    /**
     * 表头数据(第一行)
     *
     * @param titleData titleData
     * @throws Exception Exception
     */
    protected List<String> titleData(List<String> titleData) {
        return titleData;
    }

    /**
     * @description: 表数据
     * @createAuthor: 魏孟超
     * @createDate: 2021/10/17 16:17
     * @params:
     * @return:
     */
    protected abstract List<String> rowData(List<String> rowData) throws Exception;

    /**
     * 编码格式
     *
     * @return 编码格式
     */
    protected String charsetName() {
        return "UTF-8";
    }

    /**
     * @description: 获取主订单编号
     * @createAuthor: 魏孟超
     * @createDate: 2021/10/17 17:11
     * @params:
     * @return:
     */
    protected String getCellValue(String title, List<String> rowData) {
        Integer index = titleMap.get(title);
        if ((index + 1) > rowData.size()) {
            return null;
        }
        return rowData.get(index);
    }

    /**
     * @description: 替换值
     * @createAuthor: 魏孟超
     * @createDate: 2021/10/17 17:19
     * @params:
     * @return:
     */
    protected void replaceCellValue(String title, String value, List<String> rowData) {
        Integer index = titleMap.get(title);
        if ((index + 1) > rowData.size()) {
            return;
        }
        rowData.set(index, value);
    }

}
